/* 
 * Die Klasse StandortDaten repraesentiert einen Standort einer 
 * Bibliothek mit allen Daten, die dazu gehoeren, etwa Regal- und 
 * Objektpositionen.
 * 
 * Datei: Datenbank.java      Autor:  Christian Plappert
 * Datum: 08.12.2011          Version: 0.3
 * 
 * Historie: 
 * 
 * 08.12.2011:  v0.3    Integration der Medienverwaltung
 * 27.11.2011:  v0.2    Funktion gibFigur(...) implementiert, die 
 *                      Zugriff auf Standort ermoeglicht.
 * 22.11.2011:  v0.1    Klasse wurde angelegt und einige wichtige 
 *                      Listen integriert.                
 */
package bibvis;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import bibvis.FigurZustand;
import medienverwaltung.Regal;

public class StandortDaten implements Serializable
{
  private static final long serialVersionUID = 5598220761006874990L;
  private ArrayList<Regal> regalListe;
  private ArrayList<FigurZustand> rechteckListe;
  /* ObjektAufzaehlung = Tuer, Fenster, ... */
  private HashMap<ObjektAufzaehlung, ArrayList<FigurZustand>> 
    zuordnungOZ;
  private HashMap<FigurZustand, Regal> zuordnungZR;
  private HashMap<Regal, FigurZustand> zuordnungRZ;
  private HashMap<String, Integer> zuordnungSI;

  /*
   * prueft, ob sich das Objekt veraendert hat, also eine (erneute)
   * Speicherung notwendig ist.
   */
  private boolean veraendert;
  private int MASSSTAB;
  private int[] dimensionen;


  /**
   * Konstruktor initialisiert alle Listen und Objekte.
   */
  protected StandortDaten ()
  {
    regalListe = new ArrayList<Regal> ();
    rechteckListe = new ArrayList<FigurZustand> ();
    zuordnungOZ = new HashMap<ObjektAufzaehlung, 
      ArrayList<FigurZustand>> ();
    zuordnungOZ.put (ObjektAufzaehlung.TUER,
        new ArrayList<FigurZustand> ());
    zuordnungOZ.put (ObjektAufzaehlung.FENSTER,
        new ArrayList<FigurZustand> ());
    zuordnungOZ.put (ObjektAufzaehlung.THEKE,
        new ArrayList<FigurZustand> ());

    zuordnungZR = new HashMap<FigurZustand, Regal> ();
    zuordnungRZ = new HashMap<Regal, FigurZustand> ();

    zuordnungSI = new HashMap<String, Integer> ();

    dimensionen = new int[2];
    veraendert = false;
  }


  protected ArrayList<Regal> gibRegalListe ()
  {
    return regalListe;
  }


  protected ArrayList<FigurZustand> gibRechteckListe ()
  {
    return rechteckListe;
  }


  protected HashMap<FigurZustand, Regal> gibZuordnungZR ()
  {
    return zuordnungZR;
  }


  /**
   * @param regal
   */
  protected void ausAllenListenLoeschen (Regal regal)
  {
    int index;

    /* aus regalListe loeschen */
    index = regalListe.indexOf (regal);
    regalListe.remove (index);

    /* aus rechteckListe & nicht(!) aus kollisionsListe loeschen */
    index = rechteckListe.indexOf (gibZuordnungRZ ().get (regal));
    rechteckListe.remove (index);

    /* aus zuordnungZR & zuordnungRZ loeschen */
    zuordnungZR.remove (zuordnungRZ.remove (regal));
  }


  protected HashMap<Regal, FigurZustand> gibZuordnungRZ ()
  {
    return zuordnungRZ;
  }


  /**
   * Die Methode gibt die Positionen aller Objekte (Tuer, Fenster,
   * Theke) als Array-Liste zurueck.
   * 
   * @return
   */
  protected ArrayList<FigurZustand> gibZustandsListeObjekt ()
  {
    ArrayList<FigurZustand> zustaendeListe;
    zustaendeListe = new ArrayList<FigurZustand> ();

    /* @formatter:off */
    for (Map.Entry<ObjektAufzaehlung, ArrayList<FigurZustand>> e : 
      zuordnungOZ.entrySet ())
    {
      zustaendeListe.addAll (zuordnungOZ.get (e.getKey ()));
    }
    /* @formatter:on */

    return zustaendeListe;
  }


  protected HashMap<ObjektAufzaehlung, ArrayList<FigurZustand>> 
    gibObjektListe ()
  {
    return zuordnungOZ;
  }


  /**
   * Falls ein Regal bearbeitet wird, muss es in den gespeicherten
   * Listen ebenfalls geaendert werden.
   * 
   * @param altesRechteck
   * @param standort
   */
  protected void inAllenListenAendern (FigurZustand altesRechteck,
      String standort)
  {
    int index, hoehe;

    FigurZustand neuesRechteck = altesRechteck;
    Regal altesRegal = gibZuordnungZR ().get (altesRechteck);

    /*
     * Vertausche Laenge und Breite des Rechtecks, welches das Regal
     * darstellt. Vertausche aber nicht die Daten des richtigen Regals.
     * Da es ja nur gedreht wurde, bleibt die alte Laenge und Breite
     * bestehen.
     */
    hoehe = neuesRechteck.height;
    neuesRechteck.height = neuesRechteck.width;
    neuesRechteck.width = hoehe;

    index = rechteckListe.indexOf (altesRechteck);
    rechteckListe.remove (index);
    rechteckListe.add (index, neuesRechteck);

    zuordnungRZ.remove (altesRegal);
    zuordnungRZ.put (altesRegal, neuesRechteck);

    zuordnungZR.remove (altesRechteck);
    zuordnungZR.put (neuesRechteck, altesRegal);
  }


  protected ArrayList<FigurZustand> gibObjekte (ObjektAufzaehlung art)
  {
    ArrayList<FigurZustand> zustaendeListe;
    zustaendeListe = new ArrayList<FigurZustand> ();

    zustaendeListe.addAll (zuordnungOZ.get (art));

    return zustaendeListe;
  }


  /**
   * Debug-Methode mit deren Hilfe der Inhalt der Listen kontrolliert
   * werden kann.
   */
  // protected void listenAusgeben()
  // {
  // System.out.println ("\n----------------START--------------\n");
  // System.out
  // .println ("\n--------------------BibVis------------------\n");
  //
  // System.out.println ("\nRECHTECKLISTE:\n"
  // + gibRechteckListe ().size ());
  // System.out.println ("\nREGALLISTE:\n"
  // + gibRegalListe ().toString ());
  // System.out.println ("\nOBJEKTLISTE(Fenster):\n"
  // + gibObjektListe ().get (ObjektAufzaehlung.FENSTER).size ());
  // System.out.println ("\nOBJEKTLISTE(Theke):\n"
  // + gibObjektListe ().get (ObjektAufzaehlung.THEKE).size ());
  // System.out.println ("\nOBJEKTLISTE(Tuer):\n"
  // + gibObjektListe ().get (ObjektAufzaehlung.TUER).size ());
  // System.out.println ("\nZUORDNUNGZR:\n"
  // + gibZuordnungZR ().toString ());
  // System.out.println ("\nZUORDNUNGRZ:\n"
  // + gibZuordnungRZ ().toString ());
  // }

  /**
   * Alle Zustaendelisten werden in einer Liste zurueckgegeben. Dies
   * wird unter anderem fuer die Kollisionserkennung verwendet.
   * 
   * @return
   */
  protected ArrayList<FigurZustand> gibAlleZustaendeListen ()
  {
    ArrayList<FigurZustand> zustaendeListe;
    zustaendeListe = new ArrayList<FigurZustand> ();
    zustaendeListe.addAll (rechteckListe);
    for (Map.Entry<ObjektAufzaehlung, ArrayList<FigurZustand>> e : 
      zuordnungOZ.entrySet ())
    {
      zustaendeListe.addAll (zuordnungOZ.get (e.getKey ()));
    }
    return zustaendeListe;
  }


  /**
   * Die Variable gibt an, ob sich das Objekt seit dem letzten Speichern
   * geaendert hat und (de)-aktiviert gegebenfalls den Menueeintrag
   * "Speichern", sowie die Sicherheitsabfrage, on gespeichert werden
   * soll.
   */
  protected boolean gibVeraendert ()
  {
    return veraendert;
  }


  protected void setzeVeraendert (boolean veraendert)
  {
    this.veraendert = veraendert;
  }


  protected int gibMASSSTAB ()
  {
    return MASSSTAB;
  }


  protected void setzeMASSSTAB (int mASSSTAB)
  {
    MASSSTAB = mASSSTAB;
  }


  protected int[] gibDimensionen ()
  {
    return dimensionen;
  }


  protected void setzeDimensionen (int[] dimensionen)
  {
    this.dimensionen = dimensionen;
  }


  protected HashMap<String, Integer> gibZuordnungSI ()
  {
    return zuordnungSI;
  }

}
